package cn.micai.base.lambda;

import javax.swing.text.DateFormatter;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.google.common.primitives.Ints.asList;
import static java.lang.Character.isDigit;
import static org.junit.Assert.assertEquals;

/**
 * 描述：
 * <p>
 *
 * @author: 赵新国
 * @date: 2018/4/3 14:00
 */
public class LambdaTest {

    /*int count = 0;
    for (Artist artist : allArtists) {
        if (artist.isForm("Londn")) {
            count++;
        }
    }*/

    /*int count = 0;
    Iterator<Artist> iterator = allArtists.iterator();
    while(iterator.hasNext()) {
        Artist artist = iterator.next();
        if (artist.isFrom("London")) {
            count++;
        }
    }*/

    /*long count = allArtists.stream()
                             .filter(artist -> artist.isForm("London"))
                             .count();*/
    // 之过滤，不计数
    /*allArtists.stream()
              .filter(artist -> artist.isForm("London"));*/

    /*List<String> collected = new ArrayList<>();
    for (String string : asList("a", "b", "hello")) {
        String uppercaseString = string.toUpperCase();
        collected.add(uppercaseString);
    }
    assertEquals(asList("A", "B", "HELLO"), collected);*/

    /*List<String> beginningWithNumbers = new ArrayList<>();
    for(String value : asList("a", "1abc", "abc1")) {
        if (isDigit(value.charAt(0))) {
            beginningWithNumbers.add(value);
        }
    }
    assertEquals(asList("1abc"), beginningWithNumbers);*/

    public static void main(String [] args) {

        Runnable noArguments = () -> System.out.println("Hello World");

        ActionListener oneArgument = event -> System.out.println("button clicked");

        Runnable multiStatement = () -> {
            System.out.print("Hello");
            System.out.println(" World");
        };

        BinaryOperator<Long> add = (x, y) -> x + y;
        BinaryOperator<Long> addExplicit = (Long x, Long y) -> x + y;

        final String[] array = {"Hello", "world"};

        // 明确指定了泛型的类型
        Map<String, Integer> oldWordConts = new HashMap<String, Integer>();
        // 菱形操作符，不用明确声明泛型类型，编译器就可以自己推断出来
        Map<String, Integer> diamondWordConts = new HashMap<>();

        Predicate<Integer> atLeast5 = x -> x > 5;
        BinaryOperator<Long> addLong5 = (x, y) -> x + y;

        List<Integer> counts = new ArrayList<>();
        counts.add(1);
        counts.add(2);
        counts.add(3);
        counts.add(4);
        counts.add(5);
        int sum = counts.stream().mapToInt(i -> i).sum();
        System.out.println(sum);

        // collect(toList())
        /*List<String> collected = Stream.of("a", "b", "c").collect(Collectors.toList());
        assertEquals(Arrays.asList("a", "b", "c"), collected);*/

        // map
        // 使用 map 操作将字符串转换为大写形式
        List<String> collected = Stream.of("a", "b", "hello").map(string -> string.toUpperCase()).collect(Collectors.toList());
        System.out.println(collected);

        // filter
        List<String> beginningWithNumbers = Stream.of("a", "1abc", "abc2").filter(value -> isDigit(value.charAt(0))).collect(Collectors.toList());
        System.out.println(beginningWithNumbers);

        // flatMap
        List<Integer> together = Stream.of(asList(1, 2), asList(3, 4)).flatMap(numbers -> numbers.stream()).collect(Collectors.toList());
        System.out.println(together);

        // max 和 min
        // 使用 Stream 查找最短曲目
        /*List<Track> tracks = asList(new Track("Bakai", 524),
                new Track("Violets for Your Furs", 378),
                new Track("Time Was", 451));
        Track shortestTrack = tracks.stream()
                .min(Comparator.comparing(track -> track.getLength()))
                .get();
        assertEquals(tracks.get(1), shortestTrack);*/
        List<String> tracks = new ArrayList<>();
        tracks.add("Bakai");
        tracks.add("Violets for Your Furs");
        tracks.add("Time Was");
        List<String> aa = new ArrayList<>();
        tracks.stream().forEach(track -> {
            aa.add(track);
        });
        System.out.println("aa: " + aa);
        String str = tracks.stream().min(Comparator.comparing(track -> track.length())).get();
        System.out.println("str: " + str);

        // reduce reduce 操作可以实现从一组值中生成一个值
        // 使用 reduce 操作实现累加
        Integer count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);
        System.out.println(count);

        // 展开 reduce 操作
        BinaryOperator<Integer> accumulator = (acc, element) -> acc + element;
        Integer apply = accumulator.apply(
                accumulator.apply(
                        accumulator.apply(0, 1),
                        2),
                3);
        System.out.println(apply);

        // 使用命令式编程方式求和
        int acc = 0;
        for (Integer element : asList(1, 2, 3)) {
            acc = acc + element;
        }
        assertEquals(6, acc);



    }
}
